#include "NetworkDelegate.h"

#include "Network.h"

#include "cocos2d.h"

using namespace RakNet;
using namespace std;
using namespace cocos2d;

CServerHelper *CServerHelper::s_pServerHelper = NULL;

CServerHelper *CServerHelper::GetInstance()
{
	if(NULL == s_pServerHelper)
	{
		s_pServerHelper = new CServerHelper;
	}

	return s_pServerHelper;
}

//---------------------------------------------------------------------------------------------------------------------------/
void CServerHelper::ConnectServer()
{
	DisconnetAll();
	m_pAccountServer = CAccountServer::GetInstance();
	m_pAccountServer->Connect("192.168.2.191");
}

//---------------------------------------------------------------------------------------------------------------------------/
void CServerHelper::DisconnetAll()
{
	if(NULL != m_pAccountServer)
	{
		m_pAccountServer->ReleaseConnect();
		m_pAccountServer = NULL;
	}

	if(NULL != m_pGameServer)
	{
		m_pGameServer->ReleaseConnect();
		m_pGameServer = NULL;
	}
}

//---------------------------------------------------------------------------------------------------------------------------/
void CServerHelper::UserLogin(const char *szName , const char *szPsw)
{
	if(NULL == m_pAccountServer)
	{
		return;
	}
	BitStream bsSend;
	char sname[32] = {0};

	strcpy(sname, szName);

	char spsw[32] = {0};
	strcpy(spsw, szPsw);

	cocos2d::CCLog("%s, %s", sname, spsw);

	bsSend.Reset();
	bsSend.Write((MessageID)ID_GAME_ACCOUNT);

	bsSend.Write((MessageID)ID_ACCOUNTINDEX_LOGIN);
	bsSend.Write(sname,32);
	bsSend.Write(spsw, 32);
	m_pAccountServer->SendPacketToServer(bsSend);
}

//---------------------------------------------------------------------------------------------------------------------------/
void CServerHelper::UserRegister(const char *szName , const char *szPsw, std::string strEmail)
{
	if(NULL == m_pAccountServer)
	{
		return;
	}
	char sname[32];

	strcpy(sname, szName);

	char spsw[32];
	strcpy(spsw, szPsw);
	BitStream bsSend;
	bsSend.Write((RakNet::MessageID)ID_GAME_ACCOUNT);
	bsSend.Write((RakNet::MessageID)ID_ACCOUNTINDEX_REGISTER);
	bsSend.Write(sname,32);
	bsSend.Write(spsw,32);
	bsSend.Write(strEmail.c_str(),32);
	m_pAccountServer->SendPacketToServer(bsSend);
}

//---------------------------------------------------------------------------------------------------------------------------/
bool CServerHelper::ChooseRegion(int id)
{
	if(NULL == m_pAccountServer)
	{
		return false;
	}
	BitStream bsSend;
	bsSend.Write((RakNet::MessageID)ID_GAME_ACCOUNT);
	bsSend.Write((RakNet::MessageID)ID_ACCOUNTINDEX_SELECT);
	bsSend.Write(id);

	return m_pAccountServer->SendPacketToServer(bsSend);
}

//---------------------------------------------------------------------------------------------------------------------------/
bool CServerHelper::ConnectRegion()
{
	if(!m_regionUser._bGetData)
	{
		return false;
	}
	m_pGameServer = CGameServer::GetInstance();
	m_pGameServer->Connect(m_regionUser._serverAddr);

	return true;
}

//---------------------------------------------------------------------------------------------------------------------------/
bool CServerHelper::LoginRegion()
{
	if(NULL == m_pGameServer)
	{
		return false;
	}

	BitStream bsSend;
	bsSend.Write((RakNet::MessageID)ID_GAME_LOGING);
	bsSend.Write((RakNet::MessageID)ID_LOGING_LOGING);
	bsSend.Write(m_regionUser._szName, 32);
	bsSend.Write(m_regionUser._psw);

	return m_pGameServer->SendPacketToServer(bsSend);
}

//---------------------------------------------------------------------------------------------------------------------------/
bool CServerHelper::CreateRole(const RoleInfo &info)
{
	if(NULL == m_pGameServer)
	{
		return false;
	}

	BitStream bsSend;
	bsSend.Write((RakNet::MessageID)ID_GAME_LOGING);
	bsSend.Write((RakNet::MessageID)ID_LOGING_CREATENAME);
	bsSend.Write(info._szName, 32);
	bsSend.Write(info._id);

	return m_pGameServer->SendPacketToServer(bsSend);
}

//---------------------------------------------------------------------------------------------------------------------------/
bool CServerHelper::CreateRoom()
{

	if(NULL == m_pGameServer)
	{
		return false;
	}
	BitStream bsSend;
	bsSend.Write((RakNet::MessageID)ID_GAME_ROOMING);
	bsSend.Write((RakNet::MessageID)ID_ROOM_RANDOM);

	return m_pGameServer->SendPacketToServer(bsSend);

}

bool CServerHelper::CancelCreate()
{
	if(NULL == m_pGameServer)
	{
		return false;
	}
	BitStream bsSend;
	bsSend.Write((RakNet::MessageID)ID_GAME_ROOMING);
	bsSend.Write((RakNet::MessageID)ID_ROOM_RANDOM_CANCEL);

	return m_pGameServer->SendPacketToServer(bsSend);
}
//---------------------------------------------------------------------------------------------------------------------------/
bool CServerHelper::SendFightMove(const Move &moveInfo)
{
	if(NULL == m_pGameServer)
	{
		return false;
	}
	BitStream bsSend;
	bsSend.Write((RakNet::MessageID)ID_GAME_ROOMING);
	bsSend.Write((RakNet::MessageID)ID_ROOM_FIGHT);
	bsSend.Write((RakNet::MessageID)ID_FIGHT_MOVE);
	bsSend.Write((char *)&moveInfo, sizeof(moveInfo));

	return m_pGameServer->SendPacketToServer(bsSend);
}

//---------------------------------------------------------------------------------------------------------------------------/
bool CServerHelper::SendFightAttack(const AttactSend &attackInfo)
{
	if(NULL == m_pGameServer)
	{
		return false;
	}
	BitStream bsSend;
	bsSend.Write((RakNet::MessageID)ID_GAME_ROOMING);
	bsSend.Write((RakNet::MessageID)ID_ROOM_FIGHT);
	bsSend.Write((RakNet::MessageID)ID_FIGHT_ATTACT);
	bsSend.Write((char *)&attackInfo, sizeof(attackInfo));

	return m_pGameServer->SendPacketToServer(bsSend);
}

//---------------------------------------------------------------------------------------------------------------------------/
bool CServerHelper::SendRoomChat(const char *szRoom, int len)
{

	if(NULL == m_pGameServer)
	{
		return false;
	}

	BitStream bsSend;
	bsSend.Write((RakNet::MessageID)ID_GAME_ROOMING);
	bsSend.Write((RakNet::MessageID)ID_ROOM_MESSAGE);
	bsSend.Write(len);
	bsSend.Write(szRoom, len);

	return m_pGameServer->SendPacketToServer(bsSend);
}

bool CServerHelper::SendChatToName(const char *szName, const char *szMsg, int msgLen)
{
	if(NULL == m_pGameServer)
	{
		return false;
	}


	char name[32] = {0};
	strcpy(name, szName);
	BitStream bsSend;
	bsSend.Reset();
	bsSend.Write((RakNet::MessageID)ID_GAME_LOGING);
	bsSend.Write((RakNet::MessageID)ID_LOGING_MESSAGE);
	bsSend.Write(name, 32);
	bsSend.Write(msgLen);
	bsSend.Write(szMsg, msgLen);

	return m_pGameServer->SendPacketToServer(bsSend);
}
//---------------------------------------------------------------------------------------------------------------------------/
void CServerHelper::ReceivePacket()
{
	if(NULL != m_pAccountServer)
	{
		_ReceiveAccountPacket();
	}

	if(NULL != m_pGameServer)
	{
		_ReceiveGamePacket();
	}

}

//---------------------------------------------------------------------------------------------------------------------------/
void CServerHelper::_ReceiveAccountPacket()
{
	if(NULL == m_pAccountDelegate)
	{
		return;
	}

	Packet *pPacket = m_pAccountServer->GetTopPacket(); 

	if(NULL == pPacket)
	{
		return;
	}

	switch (pPacket->data[0])
	{
		CCLog("0:%d\n", pPacket->data[0]);
	case ID_CONNECTION_REQUEST_ACCEPTED:
		{
			// 连接成功
			m_pAccountDelegate->connectServerBack(true);
		}
		break;

	case ID_GAME_ACCOUNT:
		{
			switch(pPacket->data[1])
			{

				CCLog("1:%d\n", pPacket->data[1]);
			case ID_ACCOUNTINDEX_REGISTER_SUCCESS:
				{
					// 注册成功
					m_pAccountDelegate->userRegisterBack(true);
				}
				break;

			case ID_ACCOUNTINDEX_REGISTER_ERROR:
				{
					m_pAccountDelegate->userRegisterBack(false);
				}
				break;

			case ID_ACCOUNTINDEX_LOGIN_SUCCESS:
				{
					// 获取服务器选区信息

					RakNet::BitStream bsReceive(pPacket->data, pPacket->length, false);
					bsReceive.IgnoreBytes(2);

					vector<RegionInfo> vRegions;
					while(true)
					{
						RegionInfo info;

						if(!bsReceive.Read(info._id))
						{
							break;
						}

						if(!bsReceive.Read(info._userCount))
						{
							break;
						}

						if(!bsReceive.Read(info._szName, 32))
						{

							break;
						}

						vRegions.push_back(info);
					}

					// 登陆成功
					m_pAccountDelegate->userLoginBack(true, &vRegions);
				}
				break;

			case ID_ACCOUNTINDEX_LOGIN_ERROR:
				{
					// 登陆失败 密码错误
					m_pAccountDelegate->userLoginBack(false, NULL);
				}
				break;

			case ID_ACCOUNTINDEX_SELECT_SUCCESS:
				{
					// 返回选区结果,保存服务器发来的账号密码用于登陆

					RakNet::BitStream bsReceive(pPacket->data, pPacket->length, false);
					bsReceive.IgnoreBytes(2);
					memset(m_regionUser._szName, 0, 32);
					bsReceive.Read(m_regionUser._szName,32);  
					bsReceive.Read(m_regionUser._serverAddr,32);
					bsReceive.Read(m_regionUser._psw);

					m_regionUser._bGetData = true;
					m_pAccountDelegate->chooseRegionBack(true, &m_regionUser);
				}
				break;

			case ID_ACCOUNTINDEX_SELECT_ERROR:
				{
					m_pAccountDelegate->chooseRegionBack(false, NULL);
				}
				break;

			case ID_CONNECTION_LOST:
				{
					m_pAccountDelegate->accountServerLost();
				}
				break;


			default:
				{
					m_pAccountDelegate->otherAccountMsg(pPacket->data[1]);
				}
				break;
			}
		}
		break;

	default:
		//m_pAccountDelegate->otherReceiveMsg(pPacket->data[0]);
		break;
	}

	m_pAccountServer->RemoveTopPacket();
}

//---------------------------------------------------------------------------------------------------------------------------/
void CServerHelper::_ReceiveGamePacket()
{
	if(NULL == m_pGameDelegate)
	{
		return;
	}
	Packet *pPacket = m_pGameServer->GetTopPacket(); 

	if(NULL == pPacket)
	{
		return;
	}

	switch (pPacket->data[0])
	{
	case ID_CONNECTION_REQUEST_ACCEPTED:
		{
			// 连接成功
			m_pGameDelegate->connectRegionBack(true);
			m_pAccountServer->ReleaseConnect();
			m_pAccountServer = NULL;
		}
		break;

	case ID_GAME_LOGING:
		{
			// 登陆选区信息
			switch(pPacket->data[1])
			{
			case ID_LOGING_LOGING_SUCCESS:
				{
					// 登陆区域成功
					m_pGameDelegate->loginRegionBack(true);
				}
				break;

			case ID_LOGING_ERROR:
				{
					// 登陆区域失败
					m_pGameDelegate->loginRegionBack(false);
				}
				break;

			case ID_LOGING_CREATENAME:
				{
					// 获取服务器选区信息
					m_pGameDelegate->regionNoRole();
				}
				break;

			case ID_LOGING_NAME_REPEAT:
				{
					m_pGameDelegate->createNameRepeat();
				}
				break;

			case ID_LOGING_MESSAGE:
				{
					RakNet::BitStream bsReceive(pPacket->data, pPacket->length, false);
					bsReceive.IgnoreBytes(2);
					char Name[32] = {0};
					char text[256] = {0};
					int lenth = 0;

					while(1)
					{
						if(!bsReceive.Read(Name, 32))
						{
							break;
						}
						bsReceive.Read(lenth);
						bsReceive.Read(text, lenth);
						m_pGameDelegate->recvChatFromName(Name, text, lenth);
					}

				}
				break;
			}
			break;
		}
	case ID_GAME_ROOMING:
		{
			// 房间相关信息
			switch (pPacket->data[1]) 
			{
			case ID_ROOM_ANFIGHT:
				{
					// 开始战斗

					anFight p;
					RakNet::BitStream bsReceive(pPacket->data, pPacket->length, false);
					bsReceive.IgnoreBytes(2);
					bsReceive.Read((char *)&p, sizeof(p));  

					m_pGameDelegate->startFightBack(true, p);
				}
				break;

			case ID_ROOM_MESSAGE_SUCCESS:
				{
					RakNet::BitStream bsReceive(pPacket->data, pPacket->length, false);
					bsReceive.IgnoreBytes(2);
					int id;
					bsReceive.Read(id);
					char szRecv[512];
					bsReceive.Read(szRecv, pPacket->length-6);  

					m_pFightDelegate->roomChat(id, szRecv, pPacket->length-6);
				}
				break;


			case ID_ROOM_FIGHT:
				{
					if(NULL == m_pFightDelegate)
					{
						return;
					}

					switch(pPacket->data[2])
					{

					case ID_FIGHT_MOVE_SUCCESS:
						{
							Move movePacket;

							RakNet::BitStream bsReceive(pPacket->data, pPacket->length, false);
							bsReceive.IgnoreBytes(3);
							int id;
							bsReceive.Read(id);
							bsReceive.Read((char *)&movePacket, sizeof(movePacket));  

							m_pFightDelegate->enemyMove(id, movePacket);
						}
						break;

					case ID_FIGHT_ATTACT_SUCCESS:
						{
							AttactRecv attackPacket;

							RakNet::BitStream bsReceive(pPacket->data, pPacket->length, false);
							bsReceive.IgnoreBytes(3);
							int id;
							bsReceive.Read(id);
							bsReceive.Read((char *)&attackPacket, sizeof(attackPacket));  


							m_pFightDelegate->attackSuccess(id, attackPacket);
						}
						break;

					default:
						break;
					}


				}
				break;

			case ID_ROOM_USER_QUIT:
				{
					m_pGameDelegate->userLost();
				}
				break;

			default:
				break;
			}
		}
		break;
	case ID_CONNECTION_LOST:
		{
			m_pGameDelegate->gameServerLost();
		}
		break;

	case ID_DISCONNECTION_NOTIFICATION:
		{
			m_pGameDelegate->gameServerRejected();
		}
		break;
	default:
		break;
	}

	m_pGameServer->RemoveTopPacket();
}

